<?php

class lb_plugin{
	
	protected $plugins = array();
	protected $available_hooks = array();
	protected $errors = array();
	
	/**
	 * Constructor (load all enabled plugins)
	 *
	 * @author	Armin Borumand
	 */
	public function __construct(){
		global $lb;
		$this->load_hooks();
		
		$query = 'SELECT * FROM #__plugin WHERE enabled = "true" ORDER BY hook, name, sort_id';
		$params = array();
		
		$result = $lb['db']->query($query, $params);
		
		if($result['num_of_rows'] > 0){
			foreach($result['rows'] as $row){
				$row['name']  = lb_system::addslashes($row['name']);
				$row['title'] = lb_system::htmlspecialchars($row['title']);
				
				$this->plugins[$row['id']]['name']	= $row['name'];				
				$this->plugins[$row['id']]['handle']= false;
				$this->plugins[$row['id']]['title']	= $row['title'];
				$this->plugins[$row['id']]['hook']	= $row['hook'];
				$this->plugins[$row['id']]['pages']	= $row['pages'];
				$this->plugins[$row['id']]['sort_id']	= $row['sort_id'];
			}

			$this->make_handles();
		}
	}
	
	/**
	 * Make the handles of the plugins
	 *
	 * @author	Armin borumand
	 */
	protected function make_handles(){
		global $lb;
		
		foreach($this->plugins as $id=>$plugin){
			include_once($lb['dir'] . 'plugin/' . $plugin['name'] . '/' . $plugin['name'] . '.inc.php');
			$plugin_class = 'plugin_' . $plugin['name'];
			$this->plugins[$id]['handle'] = new $plugin_class;
		}
	}
	
	/**
	 * Add new plugin
	 *
	 * @author	Armin Borumand
	 * @param	string	plugin name
	 * @param	string	plugin hook
	 * @param 	string	pages
	 * @return 	boolean	true on success and false on failure!
	 */
	public function add($name, $title, $hook, $pages){
		global $lb;
		
		if(!in_array($hook, $this->hooks())){
			$this->errors[] = 'Hook not found!';
			return false;
		}
		
		if(!include_once($lb['dir'] . 'plugin/' . $name . '/' . $name . '.inc.php')){
			$this->errors[] = 'Plugin not found!';
			return false;
		}
		
		$plugin_class = 'plugin_' . $name;
		$plugin_object = new $plugin_class;
		if($plugin_object->install()){
			$query = 'INSERT INTO #__plugin (sort_id, enabled, name, title, hook, pages) ';
			$params = array(
							array($hook, 'text'),
							array(true,  'boolean'),
							array($name, 'text'),
							array($title,'text'),
							array($hook, 'text'),
							array($pages,'text')
							);
			if(in_array($hook, $this->used_hooks())){
				$query .= 'VALUES ((select max(B.sort_id) FROM #__plugin AS B WHERE hook = #) + 1, #, #, #, #, #)';
			}else{
				$query .= 'VALUES (0, #, #, #, #, #)';
				array_shift($params);
			}
			
			return $lb['db']->query($query, $params);
		}else{
			$this->errors('Error in plugin installing!');
			return false;
		}
		
		
	}

	/**
	 * Edit plugin
	 *
	 * @author	Armin Borumand
	 * @param	int		plugin id
	 * @param	string	plugin hook
	 * @param 	string	pages
	 * @return 	boolean	true on success and false on failure!
	 */
	public function edit($id, $title, $hook, $pages){
		global $lb;
		
		if(!in_array($hook, $this->hooks())){
			$this->errors[] = 'Hook not found!';
			return false;
		}
		

		$query = 'UPDATE #__plugin SET title = #, hook = #, pages = # WHERE id = #';
		$params = array(
						array($title,'text'),
						array($hook, 'text'),
						array($pages,'text'),
						array($id,	 'int')
						);
			
		return $lb['db']->query($query, $params);
		
		
	}	
	
	/**
	 * Remove plugin
	 *
	 * @author	Armin borumand
	 * @param	integer	plugin id
	 * @return	boolean	true on success and false on failure
	 */
	public function remove($id){
		global $lb;
		$query = 'SELECT sort_id, name, hook FROM #__plugin WHERE id = #';
		$params = array(
					array($id, 'int')
					);
		if(($result = $lb['db']->query($query, $params)) && $result['num_of_rows'] > 0){
			$name = $result['rows'][0]['name'];
			$hook = $result['rows'][0]['hook'];
			$sort_id = $result['rows'][0]['sort_id'];
			
			if(!include_once($lb['dir'] . 'plugin/' . $name . '/' . $name . '.inc.php')){
				$this->errors[] = 'Plugin not found!';
				return false;
			}
			
			$plugin_class = 'plugin_' . $name;
			$plugin_object = new $plugin_class;
			
			if(!$plugin_object->uninstall()){
				$this->errors[] = 'Error in plugin uninstalling!';
				return false;
			}
			
			$query = 'DELETE FROM #__plugin WHERE id = #';
			$params = array(
						array($id, 'int')
						);
			$return = $lb['db']->query($query, $params);
			
			$query = 'UPDATE #__plugin SET sort_id = sort_id - 1 WHERE hook = # AND sort_id > #';
			$params = array(
						array($hook, 'text'),
						array($sort_id, 'int')
						);
			$lb['db']->query($query, $params);
			
			return $return;
		}else{
			$this->errors[] = 'Plugin not found!';
			return false;
		}
	}

	/**
	 * Enable or disable a plugin
	 *
	 * @author	Armin Borumand
	 * @param	integer	plugin id
	 * @param	boolean	true for enable and false disable
	 * @return	boolean	true on success and false on failure
	 */
	public function enable($id, $enable=true){
	}
	
	/**
	 * change plugin position
	 *
	 * @author	Armin Borumand
	 * @param	integer	plugin id
	 * @param	string	plugin hook
	 * @param	string	new position
	 * @return	boolean	changing result
	 */
	public function change_position($id, $hook, $where){
		global $lb;
		
		switch($where){
			case 'up':
				$query = 'UPDATE #__plugins SET sort_id = # WHERE id = #';
				$params = array();
				break;
			case 'down':
				$query = '';
				$params = array();
				break;
			default:
				$query = '';
				$params = array();
		}
		
		$result = $lb['db']->query($query, $params);
		
		return $result['result'];
	}

	
	/**
	 * Load available hooks
	 *
	 * @author	Armin Borumand
	 */
	protected function load_hooks(){
		global $lb;
		
		$this->available_hooks = $lb['hooks'];
	}
	
	/**
	 * Is hook or not
	 *
	 * @author	Armin Borumand
	 * @param	string	hook
	 * @return	boolean	true on success and false on failure
	 */
	protected function is_hook($req){

		return in_array($req, $this->available_hooks);
	}
	
	/**
	 * Generate plugins content
	 * 
	 * @author	Armin Borumand
	 */
	public function get_content(){
		global $lb;
		$hooks = array();
		
		foreach($this->plugins as $id=>$plugin){
			$hooks[$plugin['hook']][$id]['title'] = $plugin['title'];
			$hooks[$plugin['hook']][$id]['name']  = $plugin['name'];
			$plugin['handle']->get_content();
		}
		
		if(is_array($hooks)){
			foreach($hooks as $hook=>$plugin){
				$lb['smarty']->assign($hook, $plugin);
			}
		}
	}
	
	/**
	 * List available plugins from plugin directory
	 * 
	 * @author	Armin Borumand
	 * @return	array	plugins
	 */
	public function available_plugins(){
		global $lb;
		$plugins = array();
		$dir = $lb['dir'] . 'plugin';
		$dh = opendir($dir);
		if(!$dh){
			return false;
		}
		
		$installed_plugins = $this->installed_plugins();

		while(($plugin = readdir($dh)) != false){
			if($plugin != '.' && $plugin != '..' && $plugin != '.svn' && !in_array($plugin, $installed_plugins)){
				$plugins[] = $plugin;
			}	
		}
		
		if(count($plugins) > 0){
			return $plugins;
		}else{
			return false;
		}
	}

	/**
	 * List installed plugins
	 * 
	 * @author	Armin Borumand
	 * @param 	boolean	plugin info or only plugin name
	 * @return	array	plugins
	 */
	public function installed_plugins($info=false){
		$plugins = array();
		
		if($info){
			return $this->plugins;
		}else{
			foreach ($this->plugins AS $plugin){
				$plugins[] = $plugin['name'];
			}
			return $plugins;
		}
	}
	
	/**
	 * List available hooks
	 * 
	 * @author	Armin Borumand
	 * @return	array	hooks
	 */
	public function hooks(){
		global $lb;
		
		return $this->available_hooks;
	}
	
	/**
	 * List used hooks
	 *
	 * @return array	used hooks
	 */
	public function used_hooks(){
		$hooks = array();
		
		foreach ($this->plugins AS $plugin){
			if(!in_array($plugin['hook'], $hooks)){
				$hooks[] = $plugin['hook'];
			}
		}
		return $hooks;
	}

	/**
	 * Return plugin informatio
	 *
	 * @param	int	$id
	 */
	function info($id){
		global $lb;
		
		$query = 'SELECT * FROM #__plugin WHERE id = #';
		$params = array(
					array($id, 'int')
					);
		if(($result = $lb['db']->query($query, $params)) && $result['num_of_rows'] > 0){
			return $result['rows'][0];
		}else{
			return false;
		}
	}
	/**
	 * Return plugin errors
	 *
	 * @return	array	errors
	 */
	public function get_errors(){
		return $this->errors;
	}

}

?>
